package cn.harry.cabinet.view.fragments

import android.app.AlertDialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.Spinner
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import cn.harry.cabinet.databinding.FragmentSerialConfigBinding
import cn.harry.cabinet.hardware.HardwareDeviceManager
import cn.harry.cabinet.hardware.device.CardReaderDevice
import cn.harry.cabinet.model.entity.HardwareDevice
import cn.harry.cabinet.model.enums.DeviceType
import cn.harry.cabinet.model.ui.CardRecordUI
import cn.harry.cabinet.model.ui.HardwareDeviceUI
import cn.harry.cabinet.repository.HardwareDeviceRepository
import cn.harry.cabinet.utils.logConfigChange
import cn.harry.cabinet.view.adapter.CardRecordAdapter
import cn.harry.cabinet.viewmodel.HardwareViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch

class SerialConfigFragment : BaseFragment() {

    private var _binding: FragmentSerialConfigBinding? = null
    private val binding get() = _binding!!

    private val hardwareViewModel: HardwareViewModel by viewModels()

    // 硬件设备配置仓库
    private lateinit var hardwareDeviceRepository: HardwareDeviceRepository

    // 刷卡器配置
    private var cardReaderConfig: HardwareDeviceUI? = null
    private var cardReaderEntity: HardwareDevice? = null

    // 刷卡器设备
    private var cardReaderDevice: CardReaderDevice? = null
    private var cardReaderListenerJob: Job? = null
    private var isCardReaderConnected = false

    // 刷卡记录列表
    private val cardRecordUIS = mutableListOf<CardRecordUI>()
    private lateinit var cardRecordAdapter: CardRecordAdapter

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentSerialConfigBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // 初始化数据库仓库
        hardwareDeviceRepository = HardwareDeviceRepository(requireActivity().application)

        // 观察刷卡器配置变化
        hardwareDeviceRepository.getDeviceByTypeLive(DeviceType.CARD_READER)
            .observe(viewLifecycleOwner) { device ->
                device?.let {
                    cardReaderEntity = it
                    cardReaderConfig = HardwareDeviceUI.fromEntity(it)
                    updateCardReaderDeviceInfo(it)
                }
            }

        // 错误信息
        hardwareViewModel.errorMessage.observe(viewLifecycleOwner) { error ->
            if (error.isNotEmpty()) {
                Toast.makeText(requireContext(), error, Toast.LENGTH_LONG).show()
                hardwareViewModel.clearErrorMessage()
            }
        }

        // 刷卡事件
        hardwareViewModel.cardReadEvent.observe(viewLifecycleOwner) { cardInfo ->
            updateCardInfo(cardInfo)
            // 显示刷卡成功提示
            Toast.makeText(requireContext(), "刷卡成功: ${cardInfo.cardId}", Toast.LENGTH_SHORT)
                .show()
        }

        // 设置点击监听器
        setupClickListeners()

        // 初始化刷卡记录列表
        setupCardRecordsList()

        // 初始化设备监听
        setupDeviceListeners()
    }

    /**
     * 设置设备监听器
     * 监听刷卡器事件
     */
    private fun setupDeviceListeners() {
        // 获取硬件设备管理器
        val hardwareManager = HardwareDeviceManager.getInstance(requireContext())

        // 设置刷卡器监听
        setupCardReaderListener(hardwareManager)
    }

    /**
     * 设置刷卡器监听
     */
    private fun setupCardReaderListener(hardwareManager: HardwareDeviceManager) {
        // 获取刷卡器设备
        cardReaderDevice = hardwareManager.getCardReaderDevice()

        if (cardReaderDevice == null) {
            android.util.Log.w(TAG, "刷卡器设备未找到")
            return
        }
        // 设置初始状态：等待用户点击连接按钮
        binding.tvCardReaderDeviceInfo.text = "设备: "
        binding.tvLastCardInfo.text = "💳 请先点击连接按钮启动刷卡器"
        binding.tvLastCardInfo.setTextColor(
            ContextCompat.getColor(
                requireContext(),
                android.R.color.darker_gray
            )
        )
        isCardReaderConnected = false
        updateCardReaderButtons()
        android.util.Log.i(TAG, "刷卡器已初始化，使用ViewModel监听刷卡事件")
    }

    /**
     * 更新刷卡器按钮状态
     */
    private fun updateCardReaderButtons() {
        binding.btnConnectCardReader.isEnabled = !isCardReaderConnected
        binding.btnDisconnectCardReader.isEnabled = isCardReaderConnected
    }

    /**
     * 初始化刷卡记录列表
     */
    private fun setupCardRecordsList() {
        cardRecordAdapter = CardRecordAdapter(requireContext(), cardRecordUIS)
        binding.rvCardRecords.apply {
            layoutManager = LinearLayoutManager(requireContext())
            adapter = cardRecordAdapter
        }
        android.util.Log.i(
            TAG,
            "刷卡记录列表已初始化, RecyclerView: ${binding.rvCardRecords != null}"
        )
    }

    private fun setupClickListeners() {
        // 刷卡器连接按钮
        binding.btnConnectCardReader.setOnClickListener {
            connectCardReader()
        }

        // 刷卡器断开按钮
        binding.btnDisconnectCardReader.setOnClickListener {
            disconnectCardReader()
        }

        // 编辑刷卡器配置按钮
        binding.btnEditCardReaderConfig.setOnClickListener {
            showCardReaderConfigDialog()
        }

        // 清空刷卡记录按钮
        binding.btnClearCardRecords.setOnClickListener {
            clearCardRecords()
        }
    }

    /**
     * 更新刷卡器设备信息显示
     */
    private fun updateCardReaderDeviceInfo(device: HardwareDevice) {
        binding.tvCardReaderDeviceInfo.text =
            "设备: ${device.deviceName} | 串口: ${device.serialPort} | 波特率: ${device.baudRate}"
    }

    /**
     * 更新卡片信息显示
     */
    private fun updateCardInfo(cardInfo: CardReaderDevice.CardInfo) {
        val timeStr = java.text.SimpleDateFormat("HH:mm:ss", java.util.Locale.getDefault())
            .format(java.util.Date(cardInfo.readTime))

        val cardText = buildString {
            append("刷卡成功!\n")
            append("原始数据: ${cardInfo.cardId}\n")
            append("类型: ${cardInfo.cardType}\n")
            append("时间: $timeStr")
        }

        binding.tvLastCardInfo.text = cardText
        binding.tvLastCardInfo.setTextColor(
            ContextCompat.getColor(
                requireContext(),
                android.R.color.holo_green_light
            )
        )

        // 添加到刷卡记录列表
        addCardRecord(cardInfo.cardId, cardInfo.cardType, cardInfo.readTime, timeStr)

        android.util.Log.i(
            TAG,
            "updateCardInfo - 卡号: ${cardInfo.cardId}, 类型: ${cardInfo.cardType}"
        )
    }


    /**
     * 手动连接刷卡器（连接串口并启动监听）
     */
    private fun connectCardReader() {
        viewLifecycleOwner.lifecycleScope.launch {
            try {
                // 从数据库获取配置
                val config = cardReaderConfig ?: run {
                    Toast.makeText(requireContext(), "刷卡器配置未加载", Toast.LENGTH_SHORT).show()
                    return@launch
                }

                // 使用 HardwareDeviceManager 连接串口
                val hardwareManager = HardwareDeviceManager.getInstance(requireContext())

                android.util.Log.i(
                    TAG,
                    "准备连接刷卡器 - 串口: ${config.serialPort}, 波特率: ${config.baudRate}"
                )

                // 检查是否已经连接
                if (!hardwareManager.isConnected.value) {
                    android.util.Log.i(TAG, "开始连接串口...")
                    val success = hardwareManager.connectAndInitialize()

                    if (!success) {
                        Toast.makeText(requireContext(), "串口连接失败", Toast.LENGTH_SHORT).show()
                        android.util.Log.e(TAG, "串口连接失败 - 路径: ${config.serialPort}")
                        return@launch
                    }

                    android.util.Log.i(TAG, "串口连接成功，等待稳定...")
                    // 等待连接稳定
                    kotlinx.coroutines.delay(500)

                    // 重新获取刷卡器设备实例
                    cardReaderDevice = hardwareManager.getCardReaderDevice()
                    android.util.Log.i(
                        TAG,
                        "刷卡器设备实例: ${if (cardReaderDevice != null) "已获取" else "null"}"
                    )
                } else {
                    android.util.Log.i(TAG, "串口已连接，直接使用现有连接")
                }

                // 启动刷卡器自动监听
                android.util.Log.i(TAG, "准备启动刷卡器自动监听...")
                cardReaderDevice?.startAutoListening()

                isCardReaderConnected = true
                updateCardReaderButtons()
                binding.tvLastCardInfo.text = "💳 刷卡器已启动，请刷卡..."
                binding.tvLastCardInfo.setTextColor(
                    ContextCompat.getColor(
                        requireContext(),
                        android.R.color.holo_blue_light
                    )
                )
                Toast.makeText(requireContext(), "刷卡器已连接", Toast.LENGTH_SHORT).show()
                android.util.Log.i(
                    TAG,
                    "✅ 刷卡器连接成功，监听已启动 - 监听串口: ${config.serialPort}"
                )

                // 记录连接刷卡器日志
                requireContext().logConfigChange(
                    scope = viewLifecycleOwner.lifecycleScope,
                    subType = "CARD_READER_CONNECT",
                    description = "连接刷卡器: ${config.deviceName}",
                    oldValue = "未连接",
                    newValue = "已连接 - 串口: ${config.serialPort}, 波特率: ${config.baudRate}"
                )

            } catch (e: Exception) {
                isCardReaderConnected = false
                updateCardReaderButtons()
                Toast.makeText(requireContext(), "连接失败: ${e.message}", Toast.LENGTH_SHORT)
                    .show()
                android.util.Log.e(TAG, "刷卡器连接失败", e)

                // 记录连接失败日志
                val config = cardReaderConfig
                requireContext().logConfigChange(
                    scope = viewLifecycleOwner.lifecycleScope,
                    subType = "CARD_READER_CONNECT",
                    description = "连接刷卡器失败: ${config?.deviceName ?: "未知设备"}",
                    oldValue = "未连接",
                    newValue = "连接失败 - 错误: ${e.message}"
                )
            }
        }
    }

    /**
     * 手动断开刷卡器（停止监听）
     */
    private fun disconnectCardReader() {
        try {
            // 停止刷卡器监听
            cardReaderDevice?.stopAutoListening()

            isCardReaderConnected = false
            updateCardReaderButtons()
            binding.tvLastCardInfo.text = "💳 已停止监听，点击连接按钮重新启动"
            binding.tvLastCardInfo.setTextColor(
                ContextCompat.getColor(
                    requireContext(),
                    android.R.color.darker_gray
                )
            )
            Toast.makeText(requireContext(), "刷卡器已停止监听", Toast.LENGTH_SHORT).show()
            android.util.Log.i(TAG, "刷卡器停止监听")

            // 记录断开刷卡器日志
            val config = cardReaderConfig
            requireContext().logConfigChange(
                scope = viewLifecycleOwner.lifecycleScope,
                subType = "CARD_READER_DISCONNECT",
                description = "断开刷卡器: ${config?.deviceName ?: "未知设备"}",
                oldValue = "已连接",
                newValue = "已断开"
            )

        } catch (e: Exception) {
            Toast.makeText(requireContext(), "断开失败: ${e.message}", Toast.LENGTH_SHORT).show()
            android.util.Log.e(TAG, "刷卡器断开失败", e)
        }
    }

    /**
     * 显示刷卡器配置编辑对话框
     */
    private fun showCardReaderConfigDialog() {
        val dialogView = layoutInflater.inflate(
            cn.harry.cabinet.R.layout.dialog_card_reader_config,
            null
        )

        val etDeviceName = dialogView.findViewById<EditText>(cn.harry.cabinet.R.id.etDeviceName)
        val etSerialPort = dialogView.findViewById<EditText>(cn.harry.cabinet.R.id.etSerialPort)
        val spinnerBaudRate =
            dialogView.findViewById<Spinner>(cn.harry.cabinet.R.id.spinnerBaudRate)

        // 设置波特率选项
        val baudRates = arrayOf("9600", "19200", "38400", "57600", "115200")
        val adapter = ArrayAdapter(
            requireContext(),
            cn.harry.cabinet.R.layout.spinner_item_dialog,
            baudRates
        )
        adapter.setDropDownViewResource(cn.harry.cabinet.R.layout.spinner_dropdown_item_dialog)
        spinnerBaudRate.adapter = adapter

        // 填充当前配置
        cardReaderConfig?.let { config ->
            etDeviceName.setText(config.deviceName)
            etSerialPort.setText(config.serialPort)
            val baudRateIndex = baudRates.indexOf(config.baudRate.toString())
            if (baudRateIndex >= 0) {
                spinnerBaudRate.setSelection(baudRateIndex)
            }
        }

        val dialog = AlertDialog.Builder(requireContext())
            .setView(dialogView)
            .create()

        // 取消按钮
        dialogView.findViewById<View>(cn.harry.cabinet.R.id.btnCancel).setOnClickListener {
            dialog.dismiss()
        }

        // 保存按钮
        dialogView.findViewById<View>(cn.harry.cabinet.R.id.btnSave).setOnClickListener {
            val deviceName = etDeviceName.text.toString().trim()
            val serialPort = etSerialPort.text.toString().trim()
            val baudRate = spinnerBaudRate.selectedItem.toString().toInt()

            // 验证输入
            if (deviceName.isEmpty()) {
                Toast.makeText(requireContext(), "请输入设备名称", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }
            if (serialPort.isEmpty()) {
                Toast.makeText(requireContext(), "请输入串口", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            // 保存配置
            saveCardReaderConfig(deviceName, serialPort, baudRate)
            dialog.dismiss()
        }

        dialog.show()
    }

    /**
     * 保存刷卡器配置到数据库
     */
    private fun saveCardReaderConfig(deviceName: String, serialPort: String, baudRate: Int) {
        lifecycleScope.launch {
            try {
                // 检查是否需要断开当前连接
                if (isCardReaderConnected) {
                    Toast.makeText(
                        requireContext(),
                        "配置已更新，请重新连接刷卡器",
                        Toast.LENGTH_LONG
                    ).show()
                    disconnectCardReader()
                }

                // 更新配置
                val updatedConfig = cardReaderConfig?.copy(
                    deviceName = deviceName,
                    serialPort = serialPort,
                    baudRate = baudRate
                ) ?: HardwareDeviceUI.getDefaultCardReaderConfig().copy(
                    deviceName = deviceName,
                    serialPort = serialPort,
                    baudRate = baudRate
                )

                // 保存到数据库（deviceType 作为主键）
                val updatedEntity = updatedConfig.toEntity()
                hardwareDeviceRepository.update(updatedEntity)
                cardReaderConfig = updatedConfig

                Toast.makeText(requireContext(), "配置已保存", Toast.LENGTH_SHORT).show()
                android.util.Log.i(
                    TAG,
                    "刷卡器配置已更新 - 设备: $deviceName, 串口: $serialPort, 波特率: $baudRate"
                )

                // 记录保存配置日志
                val oldConfig = cardReaderEntity
                val changes = mutableListOf<String>()
                if (oldConfig?.deviceName != deviceName) {
                    changes.add("设备名称: ${oldConfig?.deviceName ?: "(空)"} → $deviceName")
                }
                if (oldConfig?.serialPort != serialPort) {
                    changes.add("串口: ${oldConfig?.serialPort ?: "(空)"} → $serialPort")
                }
                if (oldConfig?.baudRate != baudRate) {
                    changes.add("波特率: ${oldConfig?.baudRate ?: "(空)"} → $baudRate")
                }

                if (changes.isNotEmpty()) {
                    requireContext().logConfigChange(
                        scope = viewLifecycleOwner.lifecycleScope,
                        subType = "CARD_READER_CONFIG",
                        description = "修改刷卡器配置: ${changes.joinToString(", ")}",
                        oldValue = "设备: ${oldConfig?.deviceName}, 串口: ${oldConfig?.serialPort}, 波特率: ${oldConfig?.baudRate}",
                        newValue = changes.joinToString("\n")
                    )
                }

            } catch (e: Exception) {
                android.util.Log.e(TAG, "保存配置失败", e)
                Toast.makeText(
                    requireContext(),
                    "保存配置失败: ${e.message}",
                    Toast.LENGTH_SHORT
                ).show()
            }
        }
    }

    /**
     * 添加刷卡记录到列表
     */
    private fun addCardRecord(
        cardId: String,
        cardType: CardReaderDevice.CardType,
        readTime: Long,
        timeStr: String
    ) {
        val record = CardRecordUI(
            cardId = cardId,
            cardType = cardType,
            readTime = readTime,
            timeStr = timeStr
        )

        // 确保在主线程上更新UI
        requireActivity().runOnUiThread {
            cardRecordAdapter.addRecord(record)
            android.util.Log.i(TAG, "添加刷卡记录: $cardId, 当前记录数: ${cardRecordUIS.size}")
            android.util.Log.i(
                TAG,
                "RecyclerView adapter item count: ${cardRecordAdapter.itemCount}"
            )
        }
    }

    /**
     * 清空刷卡记录
     */
    private fun clearCardRecords() {
        if (cardRecordUIS.isEmpty()) {
            Toast.makeText(requireContext(), "没有记录可清空", Toast.LENGTH_SHORT).show()
            return
        }

        AlertDialog.Builder(requireContext())
            .setTitle("清空记录")
            .setMessage("确定要清空所有刷卡记录吗？")
            .setPositiveButton("确定") { _, _ ->
                cardRecordAdapter.clearRecords()
                Toast.makeText(requireContext(), "已清空所有记录", Toast.LENGTH_SHORT).show()
                android.util.Log.i(TAG, "已清空所有刷卡记录")
            }
            .setNegativeButton("取消", null)
            .show()
    }

    override fun onDestroyView() {
        // 停止刷卡器监听（如果有直接监听）
        cardReaderListenerJob?.cancel()
        cardReaderDevice?.stopAutoListening()
        cardReaderDevice = null
        super.onDestroyView()
        _binding = null
    }

    companion object {
        private const val TAG = "SerialConfigFragment"
    }
}
